package sim;

import java.awt.geom.Point2D;
import java.util.Collection;

import ctf.model.Side;
import ctf.network.ProtocolError;

/**
 * The interface to all available simulator methods.
 * @author N. Bhatia, A. Butt, N. Evans, C. Levesque, P. OKeefe
 *
 */
public interface ISimulator {
	/**
	 * The available states.
	 * @author N. Bhatia, A. Butt, N. Evans, C. Levesque, P. OKeefe
	 *
	 */
	public enum State {
		START,
		VERSION,
		REQUEST_SIDE,
		NEW_ROUND,
		PLACE_FLAG,
		PLAY,
		GAME_OVER
	}
	
	/**
	 * Relays messages to the INetworkAdapter implementation.
	 * @param clientID The ID of the client to respond to.
	 * @param string The response.
	 */
	public void respond(int clientID, String string);
	
	/**
	 * Sets the state of the specified client.
	 * @param clientID The ID of the connected client.
	 * @param state The new state.
	 */
	public void setState(int clientID, State state);
	
	/**
	 * Returns the collection of Trees from the Model.
	 * @return The collection of placed trees.
	 */
	public Collection<Point2D> getTrees();

	/**
	 * Places the flag for the specified team.
	 * @param clientId The client who owns the flag.
	 * @param position The new position of the flag.
	 * @throws ProtocolError 
	 */
	public void placeFlag(int clientId, Point2D position) throws ProtocolError;
	
	/** Sets an angular velocity to a certain player on a side after a desired delay in milliseconds.
	 * @param side - side the player is on
	 * @param playerNum - the players number
	 * @param delayInMs - the desired delay time before the spin is executed.
	 * @param newAngularVelocity - the desired angular velocity that the player wants to reach.
	 * @throws ProtocolError 
	 */
	public void spinPlayer(int clientId, int playerNum, int delayInMs,
			float newAngularVelocity) throws ProtocolError;

	/**	Sets a desired acceleration to a certain player on a side after a desired delay in milliseconds.
	 * @param side - Side the player is on
	 * @param playerNum - the number of the player
	 * @param delayInMs - the desired delay before the acceleration is executed
	 * @param newAcceleration - the desired acceleration of the player.
	 * @throws ProtocolError 
	 */
	public void acceleratePlayer(int clientId, int playerNum, int delayInMs,
			float newAcceleration) throws ProtocolError;

	/**	Places the player on a side at a specific point based on his player number.
	 * @param side	- Side the player is on
	 * @param playerNum - The number of the player
	 * @param position - The position the player wants to be placed at.
	 */
	public void placePlayer(int clientId, int playerNum, Point2D position);

	/**	Sets the game time in milliseconds
	 * @param newTimeInMs - the game time in milliseconds
	 */
	public void setTime(int clientId, int newTimeInMs);
	
	/** 
	 * Gets the current game in, in ms
	 */
	public int getTime();

	/**
	 * Sets the team side of the calling client.
	 * @param clientId The ID of the client (team).
	 * @param side The side on which the client is requesting to be placed.
	 */
	public void setTeamSide(int clientId, Side side);

	/**
	 * Enables scheduling and timing of the simulators operations.
	 */
	public void play();

	/**
	 * Pauses refreshing of the model.
	 */
	public void pause();
	
	/**
	 * Resets the simulator to the initial state and configuration.
	 */
	public void reset();
	
	/**
	 * Returns the game state of the client
	 * @param clientId The requesting client
	 * @return The games state
	 */
	public String getGameState(int clientId);
}
